package org.osflash.signals;

import asunit.asserts.*;
import asunit.framework.IAsync;

class SignalDispatchArgsTest {

	@:meta(Inject())
	public var async : IAsync;
	public var completed : Signal;
	@:meta(Before())
	public function setUp() : Void {
		completed = new Signal();
	}

	@:meta(After())
	public function tearDown() : Void {
		completed.removeAll();
		completed = null;
	}

	@:meta(Test())
	public function dispatch_two_correct_value_objects_should_succeed() : Void {
		var signal : Signal = new Signal(String, uint);
		signal.dispatch("the Answer", 42);
	}

	@:meta(Test(expects="ArgumentError"))
	public function dispatch_fewer_value_objects_than_value_classes_should_should_throw_ArgumentError() : Void {
		var signal : Signal = new Signal(Date, Array);
		signal.dispatch(new Date());
	}

	@:meta(Test())
	public function dispatch_more_value_objects_than_value_classes_should_succeed() : Void {
		var signal : Signal = new Signal(Date, Array);
		signal.dispatch(new Date(), new Array<Dynamic>(), "extra value object");
	}

	@:meta(Test())
	public function dispatch_values_with_no_value_classes_defined_should_pass_to_listener() : Void {
		var signalNoValueClasses : Signal = new Signal();
		signalNoValueClasses.add(async.add(checkDispatchedValues, 10));
		signalNoValueClasses.dispatch(22, "done", new Date());
	}

	function checkDispatchedValues(a : UInt, b : String, c : Date) : Void {
		assertEquals("correct number of arguments were dispatched", 3, arguments.length);
		assertEquals("the uint was dispatched", 22, a);
		assertEquals("the String was dispatched", "done", b);
		assertTrue("a Date was dispatched", Std.is(c, Date));
	}

	@:meta(Test(expects="ArgumentError"))
	public function dispatch_one_correct_and_one_incorrect_value_object_should_throw_ArgumentError() : Void {
		var signal : Signal = new Signal(Date, Array);
		signal.dispatch(new Date(), "wrong value type");
	}

}

